package pl.s7n.paint.edits;

import java.awt.Component;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;

import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.UndoableEditSupport;

import pl.s7n.paint.commands.AbstractTransformCmd;

public class TransformEditManager extends AbstractEditManager<AbstractTransformCmd> {

  private Component       parent;
  private AffineTransform current = new AffineTransform();

  public TransformEditManager(UndoableEditSupport undoableEditSupport, Component parent) {
    super(undoableEditSupport);
    this.parent = parent;
    actions = new ArrayList<AbstractTransformCmd>();
  }

  public AffineTransform getTransform() {
    return current;
  }

  public void editPerformed(AbstractTransformCmd action) {
    super.editPerformed(action);
    recalcCurrentTransform();
    undoableEditSupport.postEdit(new TransformEdit(action));
    parent.repaint();
  }

  private void recalcCurrentTransform() {
    current = new AffineTransform();
    for (AbstractTransformCmd t : actions) {
      current.concatenate(t.getTransform());
    }
  }

  private class TransformEdit extends AbstractUndoableEdit {
    private static final long serialVersionUID = -4360907749332897740L;

    AbstractTransformCmd      newTransform;

    public TransformEdit(AbstractTransformCmd newTransform) {
      this.newTransform = newTransform;
    }

    @Override
    public String getRedoPresentationName() {
      return "Redo " + newTransform.toString();
    }

    @Override
    public String getUndoPresentationName() {
      return "Undo " + newTransform.toString();
    }

    @Override
    public void undo() {
      super.undo();
      actions.remove(newTransform);
      recalcCurrentTransform();
      parent.repaint();
    }

    @Override
    public void redo() {
      super.redo();
      actions.add(newTransform);
      current.concatenate(newTransform.getTransform());
      parent.repaint();
    }
  }
}
